<?php

namespace App\Http\Controllers;

use App\BO\Order\CreateOrder\CreateOrderInfo;
use App\BO\Order\CreateOrder\Exceptions\InvalidAddressException;
use App\BO\Order\CreateOrder\Exceptions\InvalidServiceAreaException;
use App\BO\Order\CreateOrderItemFactory;
use App\Entities\LabelEntity;
use App\Http\Requests\CreateOrderRequest;
use App\ServicesNew\CreateOrderService;
use App\Utils\GenObjFromRequestUtil;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class OrderController extends BaseController
{
    /**
     * @api {post} /order 新建订单
     * @apiGroup Order
     *
     * @apiParam {Number} addressId  地址ID
     * @apiParam {Number} productSkuId  skuID
     * @apiParam {Number} userBalance  是否使用余额
     * @apiParam {String} assignDate  下单日期
     * @apiParam {Number} assignTime  下单时间段
     * @apiParam {Number} [userCouponId]  优惠券ID
     * @apiParam {String} [remark]  备注
     * @apiParam {Array} [orderRemarksLabels]  标签备注
     */
    /**
     * @param CreateOrderRequest $request
     * @param CreateOrderService $orderService
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function store(CreateOrderRequest $request, CreateOrderService $orderService)
    {
        if (!$request->passValidate()) {  // 验证不通过
            return $this->showJsonResult(500, $request->getErrorMessage());
        }

        DB::beginTransaction();

        $createOrderInfo = $this->getCreateOrderInfo($request);
        $createOrderItem =  CreateOrderItemFactory::getByCreateOrderInfo($createOrderInfo);

        try {
            $orderEntity = $orderService->createOrder($createOrderItem);
        } catch (InvalidAddressException | InvalidServiceAreaException $e) {
            return $this->showJsonResult(500, $e->getMessage());
        } catch (\Exception $e) {
            return $this->showJsonResult(500, $e->getMessage());
        }

        $this->recordRemarkLabels($request, $orderEntity->getId());

        DB::commit();

        return $this->successJsonResult(['orderId' => $orderEntity->getId(), 'amount' => $orderEntity->getTotalAmount()]);
    }

    /**
     * @param Request $request
     * @param int $orderId
     */
    private function recordRemarkLabels(Request $request, int $orderId)
    {
        $remarkLabels = $request->input('orderRemarksLabels', []);
        if (!$remarkLabels) { // 有备注信息
            return;
        }

        $createdAt = Carbon::now()->toDateTimeString();

        $data = [];
        foreach ($remarkLabels as $labelId) {
            $label = LabelEntity::find($labelId);
            if (is_null($label)) {
                continue;
            }
            $tmp['order_remark_label_id'] = $label->getId();
            $tmp['content'] = $label->getContent();
            $tmp['order_id'] = $orderId;
            $tmp['created_at'] = $createdAt;

            $data[] = $tmp;
        }
        if (!empty($data)) {
            DB::table('order_remark_label_record')->insert($data);
        }
    }

    /**
     * @param Request $request
     * @return CreateOrderInfo
     */
    protected function getCreateOrderInfo(Request $request)
    {
        /** * @var CreateOrderInfo $createOrderInfo */
        $createOrderInfo = GenObjFromRequestUtil::getObj(CreateOrderInfo::class, $request);
        $createOrderInfo->setCityId($this->getUserLocationCityId());
        $createOrderInfo->setUserId($this->getUserId());

        return $createOrderInfo;
    }
}
